#ifndef	_THREADS_POOL_H_
#define	_THREADS_POOL_H_

#include <pthread.h>
#include <vector>
#include "JobsQueue.h"
#include "Job.h"

using namespace std;

/*
 * Manages all the working threads in the system and their Job Queues.
 * Also includes support for the main thread to help executing Jobs.
 */
class ThreadsPool
{
  public:
	/* Holds the data that each thread needs (such as it's ID, and queue) */
	struct ThreadData
	{
		size_t id;
		JobsQueue& queue;
		
		ThreadData(size_t id_, JobsQueue& queue_) : id(id_), queue(queue_) {}
	};


  private:
	size_t workerThreads;
	pthread_t *threads;
	JobsQueue *jobQueues;
	size_t lastQueue;

	/* Initializes the worker threads */
	void initializeThreads();

  public:
	/* C'tor - receives the number of worker threads to initialize (not including the one needed for the main thread) */
	ThreadsPool(size_t workerThreads);

	~ThreadsPool();

	/* Inserts a job to a queue (round-robin between queues) */
	void addJob(Job *job);

	/* Notifies all threads that no more jobs left. */
	void noMoreJobs();

	/* Notifies all threads to stop execution. */
	void stopThreads();

	/* Retrieves the queue of the main thread (so it can also execute jobs) */
	JobsQueue& getMainThreadQueue();

};

extern ThreadsPool *pool;

#endif	/* _THREADS_POOL_H_ */
